package com.caiying.dota.spider.parser.dota;

import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.context.support.ApplicationObjectSupport;
import org.springframework.stereotype.Controller;

import com.caiying.dota.domain.DotaHero;
import com.caiying.dota.domain.DotaSkill;
import com.caiying.dota.net.HttpConnector;
import com.caiying.dota.service.HeroService;
import com.caiying.dota.spider.entity.Hero;
import com.caiying.dota.util.ApplicationContextUtil;


/**
 * from http://dota.replays.net/hero/
 * 
 * @author caiying Oct 14, 2012 10:29:59 PM
 */
@Controller
public class HeroParser extends ApplicationObjectSupport{
	public enum HeroType{
		STRENGTH("hero-type-a"), 
		AGILE("hero-type-b"), 
		INTELLIGENCE("hero-type-c");
		private String str = null;
		private HeroType(String str){
			this.str = str;
		}
		@Override
		public String toString() {
			return str;
		}
	}
	public static final String A = "hero-type-a";
	public static final String B = "hero-type-b";
	public static final String C = "hero-type-c";
//	private Hero getHero(){
//		Hero hero  = new Hero(name, avatar, nickname, intro, speed, range, level, init_str, init_agi, init_int, init_per, init_hp, init_mp, init_armor, 
//				init_min_dmg, init_max_dmg, lv_str, lv_agi, lv_int, lv_armor, lv_dmg, lv_hp, dps, push, gank, ass, def, 
//				skill1_name, skill1_image, skill1_intro, skill1_desc, skill2_name, skill2_image, skill2_intro, skill2_desc, 
//				skill3_name, skill3_image, skill3_intro, skill3_desc, skill4_name, skill4_image, skill4_intro, skill4_desc);
//		return hero;
//	}
	
	public static ArrayList<Hero> getHerosForList(HeroType type){
		ArrayList<Hero> heroitems = new ArrayList<Hero>();
		String content = HttpConnector.getString("http://dota.replays.net/hero/", "UTF-8");
//		Logger.d("content", content);
		Document doc = Jsoup.parse(content);
		Element body = doc.body();
		Elements hero = body.getElementsByClass(type.toString());
		for(Element heros : hero){
			String name_cn = heros.getElementsByTag("dt").first().text();
			String name_en = heros.getElementsByTag("dt").first().getElementsByTag("span").first().text();
			System.out.println(name_cn.replace(name_en, "") + " : "+ name_en);
			Elements heross = heros.getElementsByTag("li");
			for(Element heror : heross){
				String hero_type = heror.attr("data-type");
				String hero_link = "http://dota.replays.net/"+heror.getElementsByTag("a").first().attr("href");
				String hero_thumb ="http://dota.replays.net/hero/" + heror.getElementsByTag("img").first().attr("src");
				String hero_name = heror.getElementsByTag("img").first().attr("alt");
				System.out.println("hero_type:" + hero_type+" hero_link:"+hero_link+" hero_thumb:"+hero_thumb+" hero_name:"+hero_name);
				heroitems.add(new Hero(name_cn, name_en, hero_type, hero_link, hero_thumb, hero_name));
			}
		}
		return heroitems;
	}
	
	//http://dota.replays.net/dotahero/page/Bm.shtml
	public static Hero hero(String url) throws MalformedURLException, IOException {
		Hero hero_result = null;
		try{
		String baseUrl = "http://dota.replays.net/HeroAdmin/js/"+url.substring(url.lastIndexOf("/") + 1, url.lastIndexOf("."))+".js";
		System.out.println("baseUrl="+baseUrl);
		String content = HttpConnector.getString(url, "GBK");
		System.out.println(content);
		Document doc = Jsoup.parse(content);
		Element body = doc.body();
		Element infos = body.select("div[class^=Clear]").first();
		System.out.println(infos.text());
		//<!--英雄信息-->
		Element baseinfo = infos.select("div[class^=Hero-info]").first();
		String avatar = baseinfo.getElementsByTag("img").first().attr("src");
		String heroname = baseinfo.getElementsByTag("dt").first().text();
		String heroinfo = baseinfo.getElementsByTag("dd").first().text();
		System.out.println("avatar:"+avatar+" heroname:"+heroname+" heroinfo:"+heroinfo);
		//<!--英雄模拟-->
		Element index = infos.select("div[class^=Simulator-right]").first();
		String dps = index.getElementsByClass("sim-a").first().attr("title");
		String push = index.getElementsByClass("sim-b").first().attr("title");
		String gank = index.getElementsByClass("sim-c").first().attr("title");
		String ass = index.getElementsByClass("sim-d").first().attr("title");
		String def = index.getElementsByClass("sim-e").first().attr("title");
		System.out.println(dps+" "+push+" "+gank+" "+ass+" "+def+" ");
		// 技能
		Element skill = infos.getElementById("Skills");
		Elements skill1_lv1s = skill.select("li[class^=H_Skill]");
		for(Element skill1_lv1 : skill1_lv1s){
			String skill1_lv1_img = skill1_lv1.getElementsByTag("img").first().attr("src");
			String skill1_lv1_name = skill1_lv1.getElementsByClass("H_SkillName").first().text();
			String skill1_lv1_intro = skill1_lv1.getElementsByClass("H_SkillIntro").first().text();
			System.out.println(skill1_lv1_img + " " +skill1_lv1_name+" "+skill1_lv1_intro);
			try{
			String lvs = skill1_lv1.getElementsByClass("H_SkillLevel").first().text();
			System.out.println(lvs);
			}catch(Exception e){
				e.printStackTrace();
			}
			
		}
		String skill1_name = skill1_lv1s.get(0).getElementsByClass("H_SkillName").first().text();
		String skill1_image= skill1_lv1s.get(0).getElementsByTag("img").first().attr("src");
		String skill1_intro = skill1_lv1s.get(0).getElementsByClass("H_SkillIntro").first().text();
		String skill1_desc = null;
		try{
		skill1_desc = skill1_lv1s.get(0).getElementsByClass("H_SkillLevel").first().text();
		}catch(Exception e){
			e.printStackTrace();
		}
		String skill2_name = skill1_lv1s.get(1).getElementsByClass("H_SkillName").first().text();
		String skill2_image= skill1_lv1s.get(1).getElementsByTag("img").first().attr("src");
		String skill2_intro = skill1_lv1s.get(1).getElementsByClass("H_SkillIntro").first().text();
		String skill2_desc = null;
		try{
		skill2_desc = skill1_lv1s.get(1).getElementsByClass("H_SkillLevel").first().text();
		}catch(Exception e){
			e.printStackTrace();
		}
		String skill3_name = skill1_lv1s.get(2).getElementsByClass("H_SkillName").first().text();
		String skill3_image= skill1_lv1s.get(2).getElementsByTag("img").first().attr("src");
		String skill3_intro = skill1_lv1s.get(2).getElementsByClass("H_SkillIntro").first().text();
		String skill3_desc = null;
		try{
		skill3_desc = skill1_lv1s.get(2).getElementsByClass("H_SkillLevel").first().text();
		}catch(Exception e){
			e.printStackTrace();
		}
		String skill4_name = skill1_lv1s.get(3).getElementsByClass("H_SkillName").first().text();
		String skill4_image= skill1_lv1s.get(3).getElementsByTag("img").first().attr("src");
		String skill4_intro = skill1_lv1s.get(3).getElementsByClass("H_SkillIntro").first().text();
		String skill4_desc = null;
		try{
		skill4_desc = skill1_lv1s.get(3).getElementsByClass("H_SkillLevel").first().text();
		}catch(Exception e){
			e.printStackTrace();
		}
		HashMap<String, String> heroBase = heroBaseData(baseUrl);
		DotaSkill skill1 = new DotaSkill(skill1_desc, null, skill1_image, skill1_intro, skill1_name);
		DotaSkill skill2 = new DotaSkill(skill2_desc, null, skill2_image, skill2_intro, skill2_name);
		DotaSkill skill3 = new DotaSkill(skill3_desc, null, skill3_image, skill3_intro, skill3_name);
		DotaSkill skill4 = new DotaSkill(skill4_desc, null, skill4_image, skill4_intro, skill4_name);
		Set<DotaSkill> skills = new HashSet<DotaSkill>();
		skills.add(skill1);
		skills.add(skill2);
		skills.add(skill3);
		skills.add(skill4);
		DotaHero hero = new DotaHero("level", heroname, heroname, "nickname", avatar, heroinfo, heroBase.get("Speed"), heroBase.get("Range"), 
				heroBase.get("init_str"), heroBase.get("init_str"),  heroBase.get("init_int"),heroBase.get("init_per"), heroBase.get("init_hp"), heroBase.get("init_mp"), heroBase.get("init_armor") , heroBase.get("init_min_dmg"), heroBase.get("init_max_dmg"),
				heroBase.get("lv_str"), heroBase.get("lv_agi"), heroBase.get("lv_int"), heroBase.get("lv_hp"), heroBase.get("lv_hp"), heroBase.get("lv_armor"), heroBase.get("lv_dmg"),
				dps, push, gank, ass, def,  skills);
		HeroService heroServiceBean = (HeroService)(ApplicationContextUtil.getInstance().getAppContext().getBean("heroServiceBean"));
		heroServiceBean.save(hero);
		hero_result = new Hero(heroname, avatar, "nickname", heroinfo, heroBase.get("Speed"), heroBase.get("Range"), heroBase.get("init_str"), heroBase.get("init_str"), 
				heroBase.get("init_agi"), heroBase.get("init_int"), heroBase.get("init_agi"), heroBase.get("init_hp"), heroBase.get("init_mp"), heroBase.get("init_mp"), 
				heroBase.get("init_min_dmg"), heroBase.get("init_max_dmg"), heroBase.get("lv_str"), heroBase.get("lv_agi"), heroBase.get("lv_int"), 
				heroBase.get("lv_armor"), heroBase.get("lv_dmg"), heroBase.get("lv_hp"), dps, push, gank, ass, def, 
				skill1_name, skill1_image, skill1_intro, skill1_desc, skill2_name, skill2_image, skill2_intro, skill2_desc, 
				skill3_name, skill3_image, skill3_intro, skill3_desc, skill4_name, skill4_image, skill4_intro, skill4_desc);
		}catch(Exception e){
			e.printStackTrace();
		}
		return hero_result;
	}
	
	/**
		var init_str = 21;
		var init_agi = 14;
		var init_int = 18;
		var lv_str = 2.7;
		var lv_agi = 1.3;
		var lv_int = 1.5;
		var init_hp = 549;
		var init_mp = 234;
		var init_armor = 2;
		var init_min_dmg = 50;
		var init_max_dmg = 60;
		var lv_dmg = 2.7;
		var Speed = 300;
		var Range = 128;
		var Type = "class_str";
		
		var init_per = init_agi;
		var lv_armor = 1/7;
		var lv_hp = 19;
		var lv_mp = 13;
		var level = 1;
	 */
	public static HashMap<String, String> heroBaseData(String url) throws MalformedURLException, IOException{
		DefaultHttpClient client = new DefaultHttpClient();
		HttpGet get = new HttpGet(url);
		HttpResponse response = client.execute(get);
		HttpEntity entity = response.getEntity();
		byte[] bytes = EntityUtils.toByteArray(entity);
		String content = new String(bytes, "GBK");
		System.out.println(content);
		String pattern = "var[a-zA-Z0-9_=\\.\\/\" ]+;";
		Document doc = Jsoup.parse(new String(content.getBytes("GBK"),"UTF-8"));
		Element body = doc.body();
		Matcher matcher = Pattern.compile(pattern).matcher(body.text());
		HashMap<String, String> map = new HashMap<String, String>();
		while(matcher.find()){
			String str = matcher.group();
			System.out.println(str);
			System.out.println(str.substring(4, str.indexOf("=") - 1));
			System.out.println(str.substring(str.indexOf("=") + 2, str.indexOf(";")));
			map.put(str.substring(4, str.indexOf("=") - 1), str.substring(str.indexOf("=") + 2, str.indexOf(";")));
		}
		return map;
	}
	
	public static byte[] gbk2utf8(String chenese){
		  char c[] = chenese.toCharArray();
		        byte [] fullByte =new byte[3*c.length];
		        for(int i=0; i<c.length; i++){
		         int m = (int)c[i];
		         String word = Integer.toBinaryString(m);
//		         System.out.println(word);
		        
		         StringBuffer sb = new StringBuffer();
		         int len = 16 - word.length();
		         //补零
		         for(int j=0; j<len; j++){
		          sb.append("0");
		         }
		         sb.append(word);
		         sb.insert(0, "1110");
		         sb.insert(8, "10");
		         sb.insert(16, "10");
		         
//		         System.out.println(sb.toString());
		         
		         String s1 = sb.substring(0, 8);          
		         String s2 = sb.substring(8, 16);          
		         String s3 = sb.substring(16);
		         
		         byte b0 = Integer.valueOf(s1, 2).byteValue();
		         byte b1 = Integer.valueOf(s2, 2).byteValue();
		         byte b2 = Integer.valueOf(s3, 2).byteValue();
		         byte[] bf = new byte[3];
		         bf[0] = b0;
		         fullByte[i*3] = bf[0];
		         bf[1] = b1;
		         fullByte[i*3+1] = bf[1];
		         bf[2] = b2;
		         fullByte[i*3+2] = bf[2];
		         
		        }
		        return fullByte;
		 }

}
